<template>
  <view class="content">
    <view class="containerBase">
      <live-pusher
        id="livePusher1"
        :url="livePusherUrl"
        waiting-image="https://storage.zego.im/downloads/pause_publish.png"
        v-if="isPusherShow"
        mode="SD"
        min-bitrate="800"
        max-bitrate="1500"
        @statechange="statechange"
        @netstatus="netstatus"
        @error="pusherError"
      ></live-pusher>
      <live-player
        v-for="streamItem in livePlayerList"
        :id="streamItem.streamID"
        :key="streamItem.streamID"
        :src="streamItem.url"
        autoplay
        @statechange="playStatechange"
        @netstatus="playNetstatus"
        @error="playError"
      ></live-player>
    </view>
    <scroll-view class="message-view" scroll-y="true" :scroll-into-view="scrollToView">
      <view class="message-item" v-for="(msgItem, index) in messageList" :key="index" :id="item.ID">
        <view>
          <span>{{ msgItem.name }}:</span>
          {{ msgItem.content }}
        </view>
      </view>
    </scroll-view>
    <view class="index-container">
      <view class="input-container">
        <input v-model="roomID" placeholder="请输入房间 ID" placeholder-style="color: #b3b3b3; font-size: 14px;" class="room-input" />
        <input
          v-model="inputMessage"
          confirm-type="send"
          @confirm="sendMsg"
          placeholder="说点什么吧～"
          placeholder-style="color: #b3b3b3; font-size: 14px;"
          class="msg-input"
        />
      </view>
      <view class="button-container">
        <button @click="openRoom(1)" class="roomBtn">加入房间(推流)</button>
        <button @click="openRoom(0)" class="roomBtn">加入房间(不推流)</button>
        <button @click="sendMsg" class="roomBtn">广播发送</button>
        <button @click="sendBarrageMsg" class="roomBtn">弹幕发送</button>
        <button @click="sendCustomCommand" class="roomBtn">自定义发送</button>
        <button @click="updateStreamExtra" class="roomBtn">流附加信息</button>
        <button @click="setRoomExtraInfo" class="roomBtn">发送房间附加消息</button>
      </view>
    </view>
    <view class="settings">
      <button v-if="isSettingShow" open-type="openSetting" @openSetting="settingCallback">
        授权使用摄像头和麦克风
      </button>
    </view>
  </view>
</template>

<script>
import { CommonExpress } from "../../utils/wxmini/common"
import { format } from "../../utils/wxmini/util"

export default {
  data() {
    return {
      commonExpress: null,
      roomID: "126",
      livePusherctx: "",
      livePusherUrl: "",
      isPusherShow: false,
      isSettingShow: false,
      scrollToView: "",
      messageList: [],
      inputMessage: "xxxxx",
      livePlayerList: [],
      roomUserList: []
    }
  },

  methods: {
    async openRoom(type) {
      // 0 不推流 1 推流
      await this.commonExpress.login(this.roomID)
      if (type === 1) {
        // 获取到推流地址 推流流地址
        const { url } = await this.commonExpress.getPublishStream()
        this.livePusherUrl = url
        this.isPusherShow = true
        this.$nextTick(async () => {
          // // 创建 pusher上下文 ， 一般建议在需要推流的时候，再创建上下文，以及 stateChange监听 和 netChange 监听
          this.livePusherctx = uni.createLivePusherContext("livePusher1", this)
          // this.livePusherctx.url = url  //注释掉试试
          //  开始推流，同时开启摄像头预览
          const res = await this.livePusherctx.start()
        })
      }
    },

    settingCallback(e) {
      console.log("mytag settingCallback e", e)
      if (e.errMsg.includes("ok")) {
        this.isSettingShow = false
      }
    },

    async logout() {
      // 停止推流
      if (this.livePusherctx && this.livePusherUrl) {
        this.commonExpress.zegoApi.stopPublishingStream(this.livePusherUrl)
        this.livePusherctx.stop()
      }

      // 停止拉流
      this.livePlayerList.forEach((item) => {
        this.commonExpress.zegoApi.stopPlayingStream(item.streamID)
      })
      this.livePlayerList = []

      // 退出房间服务
      const res = await this.commonExpress.zegoApi.logoutRoom()
      uni.navigateBack()
      console.log("mytag res", res)
    },

    async initCommon() {
      this.commonExpress = new CommonExpress()
      const checkRes = await this.commonExpress.checkSystemRequirements()
      this.livePlayerList = this.commonExpress.livePlayerList // 与 commonExpress中的 livePlayerList进行深拷贝。
      if (!checkRes) this.isSettingShow = true
    },
    async sendMsg() {
      const sendRes = await this.commonExpress.zegoApi.sendBroadcastMessage(this.roomID, this.inputMessage)
      if (sendRes.errorCode === 0) {
        this.pushMsg()
        console.log("mytag sendBroadcastMessage 成功")
      } else {
        console.log("mytag sendBroadcastMessage 失败", sendRes)
      }
    },

    async sendBarrageMsg() {
      const sendRes = await this.commonExpress.zegoApi.sendBarrageMessage(this.roomID, this.inputMessage)
      if (sendRes.errorCode === 0) {
        this.pushMsg()
        console.log("mytag sendBroadcastMessage 成功")
      } else {
        console.log("mytag sendBroadcastMessage 失败", sendRes)
      }
    },

    async sendCustomCommand() {
      const toUserList = this.commonExpress.roomUserList.map((item) => {
        return item.userID
      })
      console.log("mytag toUserList", toUserList)
      try {
        const sendRes = await this.commonExpress.zegoApi.sendCustomCommand(this.roomID, this.inputMessage, toUserList)
        console.log("mytag sendRes", sendRes)
        if (sendRes.errorCode === 0) {
          this.pushMsg()
        }
        console.warn("send custom success " + sendRes)
      } catch (error) {
        console.error(error)
      }
    },

    // 流附加消息
    async updateStreamExtra() {
      try {
        console.log("mytag this.commonExpress.streamID", this.commonExpress.streamID)
        this.commonExpress.zegoApi.setStreamExtraInfo(this.commonExpress.streamID, "setStreamExtraInfo test, send at " + new Date().toLocaleString())
      } catch (error) {
        console.log("mytag error updateSrteamExtra", error)
      }
    },

    async setRoomExtraInfo() {
      try {
        this.commonExpress.zegoApi.setRoomExtraInfo(this.roomID, "extraKey", "ReliableMessage test002")
      } catch (error) {
        console.log("mytag error setRoomExtraInfo", error)
      }
    },

    pushMsg() {
      let message = {
        ID: this.commonExpress.userID + new Date().getTime(),
        name: this.commonExpress.userID,
        // @ts-ignore
        time: new Date().format("hh:mm:ss"),
        content: this.inputMessage
      }
      this.messageList.push(message)
      this.scrollToView = message.ID
    },

    // live-pusher 推流状态回调
    statechange(e) {
      console.log("mytag statechange this.commonExpress.streamID, e", this.commonExpress.streamID, e)
      try {
        if (e.detail.code === -1307) {
          uni.showToast({
            icon: "none",
            title: "网络断连，且经多次重连抢救无效，更多重试请自行重启推流"
          })
        }
        this.commonExpress.zegoApi.updatePlayerState(this.commonExpress.streamID, e)
      } catch (error) {
        console.log("mytag state ", error)
      }
    },

    // live-pusher 推流网络状态通知
    netstatus(e) {
      try {
        console.warn("mytag netstatus", this.commonExpress.streamID, e)
        this.commonExpress.zegoApi.updatePlayerNetStatus(this.commonExpress.streamID, e)
      } catch (error) {
        console.log("mytag netState ", error)
      }
    },

    // live-pusher 错误
    pusherError(e) {
      console.warn("mytag pusherError", e)
    },

    // live-player 拉流状态回调
    playStatechange(e) {
      console.log("mytag player playStatechange e", e.currentTarget.id, e)
      if (e.detail.code === -1307) {
        uni.showToast({
          icon: "none",
          title: "网络断连，且经多次重连抢救无效，更多重试请自行重启推流"
        })
      }
      this.commonExpress.zegoApi.updatePlayerState(e.currentTarget.id, e)
    },

    // live-player 拉流网络状态通知
    playNetstatus(e) {
      console.log("mytag player playNetstatus", e.currentTarget.id, e)
      this.commonExpress.zegoApi.updatePlayerNetStatus(e.currentTarget.id, e)
    },

    // live-player 错误
    playError(e) {
      console.warn("mytag player pusherError", e)
    }
  },

  async mounted() {
    await this.initCommon()
  }
}
</script>

<style>
/* pages/message/index.wxss */
.containerBase {
  height: 55vh;
  padding: 10rpx;
}

live-pusher,
live-player {
  width: 45vw;
  height: 45vw;
  max-width: 200px;
  max-height: 200px;
  margin: 5rpx;
}

.message-view {
  height: 20vh;
}

.message-item span {
  color: #0d70ff;
}
.index-container {
  height: 25vh;
  border-top: 1px slategrey solid;
}
.input-container {
  border: none;
  padding-left: 10rpx;
  padding-right: 10rpx;
}
.button-container {
  border-top: 1px slategrey solid;
}
.room-input {
  display: inline-block;
  width: 26vw;
  height: 8vh;
  border-bottom: 1px solid rgba(13, 112, 255, 0.5);
  margin-right: 4vw;
}
.msg-input {
  display: inline-block;
  width: 66vw;
  height: 8vh;
  border-bottom: 1px solid rgba(13, 112, 255, 0.3);
}

.roomBtn {
  display: inline-block;
  margin: 7rpx;
  font-size: 14px;
}
</style>
